import { Module } from '@nestjs/common';
import { APP_GUARD } from "@nestjs/core";
import { AppController } from './app.controller';
import { AppService } from './app.service';

import { TypeOrmModule } from "@nestjs/typeorm";
import { UserModule } from './user/user.module';
import { User } from "./user/entities/user.entity";
import { Role } from "./user/entities/role.entity";
import { Permission } from "./user/entities/permission.entity";
import { Booking } from "./booking/entities/booking.entity";
import { RedisModule } from "./redis/redis.module";
import { EmailModule } from './email/email.module';

import { ConfigModule } from "@nestjs/config";
import { ConfigService } from "@nestjs/config";

import { JwtModule } from "@nestjs/jwt";
import { LoginGuard } from "./login.guard";
import { PermissionGuard } from "./permission.guard";
import { MeetingRoomModule } from './meeting-room/meeting-room.module';
import { MeetingRoom } from "./meeting-room/entities/meeting-room.entity";
import { BookingModule } from './booking/booking.module';
import { StatisticModule } from './statistic/statistic.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      envFilePath: "src/.env"
    }),
    /* TypeOrmModule.forRoot({
      type: "mysql",
      host: "localhost",
      port: 3306,
      username: "root",
      password: "root",
      database: "meeting_room_booking_system",
      synchronize: true,
      logging: true,
      entities: [User, Role, Permission],
      connectorPackage: "mysql2",
      extra: {
        authPlugin: "sha256_password"
      }
    }), */
    // 需要使用动态provider，就要用forRootAsync方法注册动态模块
    TypeOrmModule.forRootAsync({
      useFactory(configService: ConfigService) {
        return {
          type: "mysql",
          host: configService.get("mysql_server_host"),
          port: configService.get("mysql_server_port"),
          username: configService.get("mysql_server_username"),
          password: configService.get("mysql_server_password"),
          database: configService.get("mysql_server_database"),
          synchronize: true,
          logging: true,
          entities: [User, Role, Permission, MeetingRoom, Booking],
          connectorPackage: "mysql2",
          extra: {
            authPlugin: "sha256_password"
          }
        }
      },
      inject: [ConfigService]
    }),
    UserModule,
    RedisModule,
    EmailModule,
    JwtModule.registerAsync({
      global: true,
      useFactory(configService: ConfigService) {
        return {
          secret: configService.get("jwt_secret"),
          signOptions: {
            expiresIn: "30m" // 默认有效期30分钟
          }
        }
      },
      inject: [ConfigService]
    }),
    MeetingRoomModule,
    BookingModule,
    StatisticModule,
    
  ],
  controllers: [AppController],
  // 使用 useGlobalxxx的方式可以全局注册aop，但是无法使用 provider。
  // 如果我们想使用provider的方式全局注册 aop，就直接在AppModule中，将provider的token命名为 APP_XXX即可，nestjs会自动帮我们将provider注册为全局aop
  providers: [
    AppService,
    // 使用provider的方式注册全局Guard
    {
      provide: APP_GUARD,
      useClass: LoginGuard
    },
    {
      provide: APP_GUARD,
      useClass: PermissionGuard
    }
  ],
})
export class AppModule {}
